package frontend;

import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import backend.JProgKeeper;

import com.sun.org.apache.xerces.internal.parsers.DOMParser;

import core.Group;
import core.Study;
import core.XML.DefinesXML;
import core.XML.StudyParser;
import core.environment.Defines;

/**
 * Frontend GUI class.
 * Provides a comfortable tool for loading and running studies
 * @author Sergey and Julia
 * 
 */
public class BladeRunnerGUI extends JFrame implements WindowListener {
	private static final long serialVersionUID = -2428118267756844995L;
	private Study study;

	JPanel canvas = new JPanel();
	JButton btRun = new JButton("Run");
	JButton btLoadStudy = new JButton("Load Study XML");
	private JTree studyTree;
	JProgKeeper progressBar;
	Thread exeThread = null;
	private Boolean runFlag = null;

	/**
	 * Constructor for the GUI
	 */
	@SuppressWarnings("nls")
	public BladeRunnerGUI() {
		super("Blade runner");
		this.study = null;

		
		this.progressBar = new JProgKeeper();

		this.btLoadStudy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				loadStudy();
				
			}

		});
		
		this.btRun.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				runAll();
			}

		});

		this.setLocation(300, 300);
		this.canvas.add(this.btLoadStudy);
		this.canvas.add(this.btRun);
		this.progressBar.jpb.setVisible(false);
		this.progressBar.jpb.setStringPainted(true);

		this.canvas.add(this.progressBar.jpb);
		this.btRun.setEnabled(false);
		addWindowListener(this);
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		this.add(this.canvas);
		this.pack();
		this.setVisible(true);
		this.setEnabled(true);
	
	}

	@SuppressWarnings({ "deprecation", "boxing" })
	void pause() {
		this.exeThread.suspend();
		this.runFlag = false;
		this.btRun.setText("Run");
	}
	
	@SuppressWarnings({ "boxing", "deprecation" })
	void runAll() {
		if (this.study == null) {
			JOptionPane.showMessageDialog(null, "No study files were loaded",
					"Study missing", JOptionPane.ERROR_MESSAGE);
			return;
		}
	

		if (this.runFlag == null) {
			this.progressBar.jpb.setVisible(true);
			
			
			this.exeThread = new Thread() {
				public void run() {
					execute();
				}
				
			};
			this.runFlag = true;
			this.exeThread.start();
		}

		else if (this.runFlag == true) {
			pause();
			return;
		}
		
		else if (this.runFlag == false) {
			this.runFlag = true;
			this.exeThread.resume();
		}
		
		this.btRun.setText("Pause");
		this.pack();
		
	}

	void execute() {
		this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
		this.study.execute();
		this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		this.btRun.setEnabled(false);
		this.btLoadStudy.setEnabled(false);
		JOptionPane.showMessageDialog(null, this.study.getName() + " is done!", "Study state", JOptionPane.INFORMATION_MESSAGE  );
	}
	void loadStudy() {
		Document doc = getParser();
		if (doc != null) {
			try {
			this.study = StudyParser.parseStudy(doc.getElementsByTagName(
					DefinesXML.XML_STUDY).item(0));
			createTree();
			this.btRun.setEnabled(true);
			this.study.setProgresser(this.progressBar);
			}
			catch (Exception e) {
				JOptionPane.showMessageDialog(null, "<html><u>There was a problem parsing the XML file. </u><br>Please check its syntax with some XML validating tool.<br> Even opening it in a browser might shed some light on the problem.</html>",
						"Study missing", JOptionPane.ERROR_MESSAGE);
			}

		}
		
		
	}

	void createTree() {
		
		DefaultMutableTreeNode root = new DefaultMutableTreeNode(this.study
				.getName());

		for (Group g : this.study.getGroups()) {
				root.add(new DefaultMutableTreeNode(g.getName()));
			}

		try {
		this.canvas.remove(this.studyTree);
		}catch(Exception e) {//stub
		}
		this.studyTree = new JTree(root);
		this.canvas.add(this.studyTree);
		this.pack();
		 
	}

	private Document getParser() {
		File xml = getFileName();
		if (xml == null)
			return null;

		DOMParser parser = new DOMParser();
		try {
			parser.parse(xml.getAbsolutePath());
		} catch (SAXException e) {
			Defines.printException(e.getMessage());
		} catch (IOException e) {
			Defines.printException(e.getMessage());
		}
		return parser.getDocument();

	}

	private File getFileName() {
		// open in working directory
		final JFileChooser fc = new JFileChooser(".");
		fc.showOpenDialog(this);
		return fc.getSelectedFile();
	}

	@SuppressWarnings("deprecation")
	@Override
	public void windowClosing(WindowEvent e) {

		// default icon, custom title
		int n = JOptionPane.showConfirmDialog(this,
				"Are you sure you want to exit?", "Exit",
				JOptionPane.YES_NO_OPTION);
		if (n == JOptionPane.YES_OPTION) {
			this.dispose();
			if (null != this.exeThread)
				this.exeThread.stop();
			
		}

	}

	@Override
	public void windowDeactivated(WindowEvent e) {
		// Auto-generated method stub

	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		// Auto-generated method stub

	}

	@Override
	public void windowIconified(WindowEvent e) {
		// Auto-generated method stub

	}

	@Override
	public void windowOpened(WindowEvent e) {
		// Auto-generated method stub

	}

	@Override
	public void windowActivated(WindowEvent e) {
		// Auto-generated method stub

	}

	@Override
	public void windowClosed(WindowEvent e) {
		// Auto-generated method stub

	}

}
